#include "ComponentLoot.h"
#include "Components/ComponentOnFire.h"
#include "Components/ComponentCreature.h"
#include "Components/ComponentHealth.h"
#include "Components/ComponentBody.h"
#include "Subsystems/SubsystemTimeOfDay.h"
#include "Subsystems/SubsystemPickables.h"
#include "GameSingleton.h"
#include "GameRandom.hpp"
#include "GameRegistry.hpp"
#include "GameThreadPool.hpp"

#include "Engine/Vector3.hpp"

namespace PocketSurvival
{
    void ComponentLoot::update(float dt)
    {
        SubsystemTimeOfDay *timeOfDay = GameSingleton::singletonPtr->getSingleton<SubsystemTimeOfDay>();
        SubsystemPickables *pickables = GameSingleton::singletonPtr->getSingleton<SubsystemPickables>();

        if (lootDropped == false &&
            componentCreature->componentHealth->deathTime > 0 &&
            timeOfDay->getGameTime() - componentCreature->componentHealth->deathTime >= componentCreature->componentHealth->corpseDuration)
        {
            bool isOnFire = false;
            lootDropped = true;

            ComponentOnFire **componentOnFirePtr = GameSingleton::gameRegistry->try_get<ComponentOnFire *>(entity);
            if (componentOnFirePtr != nullptr)
            {
                isOnFire = ((*componentOnFirePtr)->fireDuration > 0);
            }

            std::vector<Loot> &theLootVec = (isOnFire ? lootOnFireVec : lootVec);
            for (const Loot &item : theLootVec)
            {
                if (GameSingleton::gameRandom->getFloat(0.0f, 1.0f) < item.probability)
                {
                    int32_t count = GameSingleton::gameRandom->getInt(item.minCount, item.maxCount);
                    for (int32_t index = 0; index < count; index++)
                    {
                        BoundingBox boundingBox = componentCreature->componentBody->getBoundingBox();
                        Vector3 position = (boundingBox.Min + boundingBox.Max) / 2.0f;
                        pickables->addPickable(item.blockValue, 1, position, nullptr, nullptr);
                    }
                }
            }
        }
    }


    static const std::string componentName = "Loot";
    const std::string &ComponentLoot::getName() const
    {
        return componentName;
    }
    const std::string &ComponentLoot::GetName()
    {
        return componentName;
    }

    void ComponentLoot::load(const nlohmann::json &jsonData)
    {
        componentCreature = GameSingleton::gameRegistry->get<ComponentCreature *>(entity);

        lootDropped = jsonData["LootDropped"].get<bool>();
        lootVec = jsonData["Loot"].get<std::vector<Loot>>();
        lootOnFireVec = jsonData["LootOnFire"].get<std::vector<Loot>>();
    }

    void ComponentLoot::save(nlohmann::json &jsonData)
    {
        jsonData["LootDropped"] = lootDropped;
    }
} // namespace PocketSurvival
